home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Devices / Qwertytunes / BigEasy2.c next >
Encoding:
C/C++ Source or Header  |  1993-03-03  |  41.3 KB  |  2,094 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        BigEasy2.c
  3.  
  4.     Copyright:    © 1990-1992 by Apple Computer, Inc., all rights reserved.
  5.  
  6.     This file is used in these builds: Warhol
  7.  
  8.     Change History (most recent first):
  9.  
  10.         <35>      1/7/93    dvb        Compile under mpw.
  11.         <34>      1/6/93    dvb        Built in window-copy command.
  12.         <33>     4/23/92    dvb        Test checkout from new project
  13.         <32>     4/13/92    dvb        Pass activate/deactivates to back windows.
  14.         <31>     3/22/92    dvb        QuitApp message.
  15.         <30>     1/20/92    dvb        Cool new features. Much easier appleevents.
  16.         <29>    12/19/91    JB        removing think 4.0 code
  17.         <28>    10/14/91    JB        added #ifdef to create old window ports for debugging
  18.         <27>     9/18/91    PH        support silly disk inserted events
  19.         <26>     8/12/91    MD        support for timing profiler nastiness
  20.         <25>      7/3/91    PH        qd. is bad under old think
  21.         <24>     6/28/91    dvb        Make it work with/without MacHeaders in LSC5.
  22.         <23>      6/4/91    PH        compilin'
  23.         <22>      6/3/91    dvb        Just hackin.
  24.         <21>     5/28/91    JB        Added prototypes for BigEasy Proc Ptrs
  25.         <20>     5/27/91    PH        to compile again...
  26.         <19>     5/25/91    JB        OLD_THINK_C && TOOLBOX_LINKED
  27.         <18>     5/23/91    PH        changes for THINK 5
  28.         <17>     5/22/91    PH        new style prototypes
  29.         <16>      5/6/91    PH        nifty line after about...
  30.         <15>      5/5/91    dvb        Latest features, and App-Events for document open.
  31.        
  32.         <14>     4/25/91    JB        Changing to new THINK C interface files
  33.         <13>     4/19/91    PH        i like content clicks
  34.         <12>     4/19/91    dvb        Add WindowEventProc
  35.         <11>     3/29/91    PH        minor activate fix
  36.         <10>     3/29/91    dvb        Repair deactivate vs closewindow conflict, roll in latest cool
  37.                                     features.
  38.          <9>      3/9/91    dvb        Adjust to work with or without (LSC) mac headers
  39.          <8>      3/7/91    JB        Adjusting for using MacHeaders
  40.          <7>      3/1/91    dvb        Trivial new functions
  41.          <6>     2/24/91    dvb        Various cool new calls
  42.          <5>     2/18/91    dvb        Miscellaneous Updates
  43.          <4>      1/9/91    JB        Increasing ItemsPerMenu & #Menus
  44.          <3>    11/21/90    JB        Changes for INIT & mpw compatability
  45.          <2>    11/17/90    dvb        Pass on unused command-keys to document windows
  46.         <1>    11/17/90    dvb        New again after 1st CD pressing! Yay!
  47.  
  48.     To Do:
  49. */
  50.  
  51. /* file: BigEasy2.c
  52.   *
  53.   * Started 30 June 1988, more or less.
  54.   *
  55.   * A set of routines to allow the quick development
  56.   * of simple Macintosh applications.
  57.   * :)
  58.   */
  59.  
  60.  
  61. #define BigEasy2
  62.  
  63. #include <QuickDraw.h>
  64. #include <GestaltEqu.h>
  65. #include <Events.h>
  66. #include <AppleEvents.h>
  67. #include <Resources.h>
  68. #include <Menus.h>
  69. #include <ToolUtils.h>
  70. #include <Menus.h>
  71. #include <Windows.h>
  72. #include <Dialogs.h>
  73. #include <Memory.h>
  74. #include <Desk.h>
  75. #include <Fonts.h>
  76. #include <OSEvents.h>
  77. #include <Scrap.h>
  78. #include <SegLoad.h>
  79.  
  80. /* #define THINK_C_PROFILE /* */
  81. #if defined(TIMING_PROFILE) || defined(STACK_KILLER)
  82.     #include "stack killer.h"
  83. #endif
  84.  
  85. #include "BigEasy2.h"
  86.  
  87. /*----------------
  88.     Limits
  89. ----------------*/
  90. #define kMMax 10            /* Number of menus in menubar */
  91. #define kMIMax 50            /* Number of items per menu */
  92. #define kMenuNameMax 32        /* Length of a menu title */
  93.  
  94. #define kStagStepX 7
  95. #define kStagStepY 7
  96. #define kStagLimX 97
  97. #define kStagLimY 37
  98.  
  99. /*----------------
  100.     Constants
  101. ----------------*/
  102. #define    kOSEvent                        app4Evt    /* event used by MultiFinder */
  103. #define    kSuspendResumeMessage            1        /* high byte of suspend/resume event message */
  104. #define    kResumeMask                    1        /* bit of message field for resume vs. suspend */
  105.  
  106. #define kWinPosType 'bewP'
  107. #define trapExitToShell 0xA9F4
  108.  
  109.  
  110.  
  111. /*----------------
  112.     Major BigEasy2 Structures
  113. ----------------*/
  114.  
  115. typedef struct TEasyWindow
  116.     {
  117.     Boolean wUsed;
  118.     long id;
  119.     long flags;
  120.     Boolean wGrowable;
  121.     beUpdateProcPtr wUpdateProc;
  122.     beClickProcPtr wClickProc;
  123.     beKeyProcPtr wKeyProc;
  124.     beGoAwayProcPtr wGoAwayProc;
  125.     beWNumCallProcPtr wZoomProc;
  126.     beActivateProcPtr wActivateProc;
  127.     beDeactivateProcPtr wDeactivateProc;
  128.     beIdleProcPtr wIdleProc;
  129.     beResizeProcPtr wResizeProc;
  130.     beGrowWindowProcPtr wGrowWindowProc;
  131.     beMoveWindowProcPtr wMoveWindowProc;
  132.     beEventProcPtr wEventProc;
  133.     WindowPtr wWindow;
  134.     } TEasyWindow;
  135.  
  136. typedef struct
  137.     {
  138.     short ref;
  139.     char mark;
  140.     char enable;
  141.     char cmdEquiv;
  142.     beMenuProcPtr proc;
  143.     } TEasyMenuItem;
  144.  
  145. /*----------------
  146.     Globals
  147. ----------------*/
  148. static short gIdleSeed;
  149. static Rect gResizeLim = {50,50,1000,1000};
  150. static TEasyWindow **gEasyWindowListH;            /* Handle to array of window objects    */
  151. static TEasyWindow *gEasyWindowList;            /* Pointer to array of window objects    */
  152. static short gEasyWindowListSize;                /* Number of window objects allocated    */
  153.  
  154. /*** Menus ***/
  155. static MenuHandle gMenuHandleList[kMMax];        /* MenuHandles indexed by MenuID's         */
  156. static short gMenuLength[kMMax];
  157. static char gMenuName[kMMax][kMenuNameMax];
  158. static TEasyMenuItem gMenu[kMMax][kMIMax];
  159. static short gMenuCount;                        /* How many menus defined */
  160. static short gCurrentMenu;                        /* the one to add to */
  161. static MenuHandle gMenuEdit;                    /* Which one is the edit menu? */
  162.  
  163. /*** Phantom Menu ***/
  164. static MenuHandle phantomMenuH = 0;
  165.  
  166. /*** About ***/
  167. static beAboutProcPtr gAboutProc;
  168. static char gAboutS0[256];
  169.  
  170. /*** Application Edit Commands ***/
  171. static beWNumCallProcPtr gAppUndoProc,gAppCutProc,gAppCopyProc,gAppPasteProc,gAppClearProc;
  172.  
  173. /*** Global Status ***/
  174. static beOpenAppProcPtr gMasterOpenAppProc;
  175. static beOpenDocProcPtr gMasterOpenDocProc;
  176. static beQuitAppProcPtr gMasterQuitAppProc;
  177.  
  178. static beAboutProcPtr gMasterIdleProc;
  179. static short gStagX,gStagY;
  180. static WindowPtr gLastFrontIdle;
  181. static short gLastFrontWindowNumber;
  182. static short gSleep;
  183. static short gCoolDragState;
  184. static Point gCoolDragPoint;
  185. static short gCoolDragWindowNumber;
  186. static TEasyWindow *gCoolDragEW;
  187. static Boolean gInvalidMenuBar;
  188.  
  189. static void *gOldExitToShell;
  190.  
  191. /*----------------
  192.     Prototypes
  193. ----------------*/
  194. static void InitToolbox(void);
  195. static void CheckMenubar(void);
  196. static void EventLoop(void);
  197. static void InitBigEasy(void);
  198. static void InstallMyExitToShell(void);
  199. static pascal void MyExitToShell(void);
  200. static void GetGrowRect(WindowPtr,Rect*);
  201. static void EnoughEasyWindows(short);
  202. static void FrontDAEdits(void);
  203. static TEasyWindow *GoodWNum(short);
  204. static Boolean CoolBigEasyCmdKeys(short key);
  205.  
  206. static void DoMyAbout(void);
  207. static void BEUndo(short);
  208. static void BECopy(short);
  209. static void BECut(short);
  210. static void BEPaste(short);
  211. static void BEClear(short);
  212. static void BENull(void);
  213. static void MenuClick(Point p);
  214. static void DeleteIndexedMenuItem(short menu,short item);
  215. static Boolean DoKeyPress(long k);
  216. static void MenuPoint(long theclick);
  217. static void StartMenus(void);
  218. static short ScanWindowList(WindowPtr w);
  219. static void DoMouseClick(EventRecord *event);
  220. static void MyDrawGrowIcon(WindowPtr w);
  221.  
  222. static pascal OSErr BigEasyOpenAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  223. static pascal OSErr BigEasyOpenDocThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  224. static pascal OSErr BigEasyQuitAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  225. static OSErr MissedAEParameters (AppleEvent *message);
  226.  
  227. Boolean ActivateWindow(WindowPtr w, Boolean activate);
  228.  
  229.  
  230. void main(void);
  231.  
  232. /*----------------
  233.     Some useful routines
  234. ----------------*/
  235.  
  236. void InitToolbox(void)
  237.     {
  238.     InitGraf(&qd.thePort);
  239.     InitFonts();
  240.     FlushEvents(0xffff,0);
  241.     InitWindows();
  242.     InitMenus();
  243.     InitDialogs(0);
  244.     TEInit();
  245.     InitCursor();
  246.     }
  247.  
  248.  
  249. void GetGrowRect(WindowPtr w,Rect *r)
  250.     {
  251.     register Rect *gr;
  252.  
  253.     gr = r;
  254.     *gr = w->portRect;
  255.     gr->left = gr->right - 15;
  256.     gr->top = gr->bottom - 15;
  257.     }
  258.  
  259. void GoWatch(void)
  260.     {
  261.     SetCursor(*(Cursor**)GetCursor(4));
  262.     }
  263.  
  264. void GoArrow(void)
  265.     {
  266.     SetCursor(&qd.arrow);
  267.     }
  268.  
  269. void GoCursor(short c)
  270. /*
  271.   * Attempt to set to cursor ID c,
  272.   * but skip it if not there.
  273.   */
  274.     {
  275.     register Cursor **cur;
  276.  
  277.     cur = (Cursor **)GetCursor(c);
  278.     if(cur)
  279.         SetCursor(*cur);
  280.     }
  281.  
  282. static void EnoughEasyWindows(short n)
  283. /*
  284.   * If there are less than n window objects in the list,
  285.   * grow the handle appropriately.
  286.   */
  287.     {
  288.     short i;
  289.  
  290.     n++;
  291.     if(gEasyWindowListSize < n)
  292.         {
  293.         HUnlock((Handle)gEasyWindowListH);
  294.         SetHandleSize((Handle)gEasyWindowListH,sizeof(TEasyWindow) * (long)n);
  295.         HLock((Handle)gEasyWindowListH);
  296.         gEasyWindowList = *gEasyWindowListH;
  297.  
  298.         for(i = gEasyWindowListSize; i < n; i++)
  299.             gEasyWindowList[i].wUsed = 0;
  300.  
  301.         gEasyWindowListSize = n;
  302.         }
  303.     }
  304.  
  305. static TEasyWindow *GoodWNum(short n)
  306. /*
  307.   * return true if n is the number of an
  308.   * existing, used window.
  309.   */
  310.     {
  311.     register TEasyWindow *thisWindow;
  312.     if(n<0 || n>=gEasyWindowListSize)
  313.         return 0;
  314.     thisWindow = &gEasyWindowList[n];
  315.     if(thisWindow->wUsed)
  316.         return thisWindow;
  317.     else
  318.         return 0;
  319.     }
  320.  
  321.  
  322. static void FrontDAEdits(void)
  323. /*
  324.  * Check the front window. If it's a DA,
  325.  * enable all edit menu options.
  326.  */
  327.     {
  328.     WindowRecord *w;
  329.  
  330.     w = (WindowRecord*)FrontWindow();
  331.     if(w->windowKind < 0)                                    /* Any click in a DA window: */
  332.         EnDisEdits(1,1,1,1,1);                                /* enable edit menu. */
  333.     }
  334.  
  335.  
  336. void DoMyAbout(void)
  337.     {
  338.     DialogPtr d;
  339.     Handle h;
  340.     short hit;
  341.  
  342.     if(gAboutProc)
  343.         (*gAboutProc)();
  344.     else
  345.         {
  346.         h = GetResource('DLOG',1962);                            /* does it exist? */
  347.         if( (ResError()==0) && (h!=nil) )
  348.             {
  349.             ParamText((StringPtr)gAboutS0,0,0,0);
  350.             d = GetNewDialog(1962,0,(WindowPtr)-1);
  351.             ModalDialog(nil,&hit);
  352.             DisposDialog(d);
  353.             }
  354.         }
  355.     }
  356.  
  357. void SetMasterIdle(r)
  358.     beAboutProcPtr r;
  359.     {
  360.     gMasterIdleProc = r;
  361.     }
  362.  
  363. void SetWindowResizeProc(short n,beResizeProcPtr resizeProc)
  364. /*
  365.   * Sets the procedure which gets called when the window is resized
  366.   */
  367.     {
  368.     TEasyWindow *thisWindow;
  369.  
  370.     thisWindow = GoodWNum(n);
  371.     if(thisWindow)
  372.         thisWindow->wResizeProc = resizeProc;
  373.     }
  374.  
  375. void SetWindowGrowWindowProc(short n,beGrowWindowProcPtr growWindowProc)
  376. /*
  377.   * Sets the procedure which gets called when the window grows.
  378.   *   Allows alternate to GrowWindow.
  379.   */
  380.     {
  381.     TEasyWindow *thisWindow;
  382.  
  383.     thisWindow = GoodWNum(n);
  384.     if(thisWindow)
  385.         thisWindow->wGrowWindowProc = growWindowProc;
  386.     }
  387.  
  388. void SetWindowMoveProc(short n,beMoveWindowProcPtr moveWindowProc)
  389.     {
  390.     TEasyWindow *thisWindow;
  391.  
  392.     thisWindow = GoodWNum(n);
  393.     if(thisWindow)
  394.         thisWindow->wMoveWindowProc = moveWindowProc;
  395.     }
  396.  
  397.  
  398. void SetWindowZoomProc(short n,beWNumCallProcPtr zoomProc)
  399.     {
  400.     register TEasyWindow *thisWindow;
  401.  
  402.     thisWindow = GoodWNum(n);
  403.     if(thisWindow)
  404.         thisWindow->wZoomProc = zoomProc;
  405.     }
  406.  
  407. void SetWindowEventProc(short n,beEventProcPtr eventProc)
  408.     {
  409.     register TEasyWindow *thisWindow;
  410.  
  411.     thisWindow = GoodWNum(n);
  412.     if(thisWindow)
  413.         thisWindow->wEventProc = eventProc;
  414.     }
  415.  
  416. long GetWindowFlags(short n)
  417.     {
  418.     TEasyWindow *thisWindow;
  419.  
  420.     if(!(thisWindow = GoodWNum(n)))
  421.         return 0;
  422.  
  423.     return thisWindow->flags;
  424.     }
  425.  
  426. void SetWindowFlags(short n,long flags)
  427.     {
  428.     TEasyWindow *thisWindow;
  429.  
  430.     if(!(thisWindow = GoodWNum(n)))
  431.         return;
  432.  
  433.     thisWindow->flags = flags;
  434.     }
  435.  
  436. void SetAbout(StringPtr progName,StringPtr s0,beAboutProcPtr aboutProc)
  437. /*
  438.  * Sets the program's name in the about box, and
  439.  * sets the second string as ParamText 0 (^0)
  440.  * for the about dialog, 1962.
  441.  */
  442.     {
  443.     short i;
  444.     
  445.     SetItem(gMenuHandleList[1],1,(StringPtr)progName);
  446.  
  447.     for(i=0; i<256; i++)
  448.         gAboutS0[i] = *s0++;
  449.  
  450.     gAboutProc = aboutProc;
  451.     } 
  452.  
  453. /*----------------
  454.     Error Handling
  455. ----------------*/
  456.  
  457. void InstallMyExitToShell(void)
  458. /*
  459.   * Add my HatStrap call to
  460.   * the classic routine, "ExitToShell"
  461.   */
  462.     {
  463.     gOldExitToShell =  (void *) NGetTrapAddress(trapExitToShell, ToolTrap);
  464.     NSetTrapAddress((long) MyExitToShell, trapExitToShell, ToolTrap);
  465.     }
  466.  
  467. pascal void MyExitToShell(void)
  468. /*
  469.   * My exit routine, which does
  470.   * all the good cleanup.
  471.   */
  472.     {
  473.     Hatstrap();
  474.     NSetTrapAddress((long) gOldExitToShell, trapExitToShell, ToolTrap);
  475.     ExitToShell();
  476.     }    
  477.  
  478. void FailNil(long x)
  479. /*
  480.   * If x is zero, post an error
  481.   * alert and quit the program.
  482.   */
  483.     {
  484.     if(!x)
  485.         {
  486.         Alert(200,nil);
  487.         Debugger();
  488.         ExitToShell();
  489.         }
  490.     }
  491.  
  492. void FailOSErr(long x)
  493. /*
  494.   * If x isn't zero, post an error
  495.   * alert and quit the program.
  496.   */
  497.     {
  498.     if(x)
  499.         {
  500.         Debugger();
  501.         Alert(200,nil);
  502.         ExitToShell();
  503.         }
  504.     }
  505.  
  506. /*----------------
  507.     Some inherent methods
  508. ----------------*/
  509.  
  510. void BEUndo(short n)
  511.     {
  512.     if(!SystemEdit(0))
  513.         (*gAppUndoProc)(n);
  514.     }
  515.  
  516. void BECut(short n)
  517.     {
  518.     if(!SystemEdit(2))
  519.         (*gAppCutProc)(n);
  520.     }
  521.  
  522. void BECopy(short n)
  523.     {
  524.     TEasyWindow *thisEasyWindow;
  525.  
  526.     if(!SystemEdit(3))
  527.         {
  528.         thisEasyWindow = GoodWNum(n);
  529.         if(thisEasyWindow->flags & wCopyDraw)
  530.             /*
  531.              * 
  532.              */
  533.             {
  534.             Rect visBounds;
  535.             beUpdateProcPtr fp;
  536.             PicHandle picH;
  537.  
  538.             visBounds = qd.thePort->portRect;
  539.             ClipRect(&visBounds);
  540.  
  541.             picH = OpenPicture(&visBounds);
  542.  
  543.             fp = thisEasyWindow->wUpdateProc;
  544.             if(fp)
  545.                 {
  546.                 SetPort(thisEasyWindow->wWindow);    /* Set port to window    */
  547.                 (*fp)(n);                            /* Call drawing proc    */
  548.                 }
  549.  
  550.             SetOrigin(0,0);
  551.  
  552.             ClosePicture();
  553.             ClipRect(&gBigRect);
  554.  
  555.             HLock((Handle)picH);
  556.             ZeroScrap();
  557.             PutScrap(GetHandleSize((Handle)picH),'PICT',(Ptr)*picH);
  558.  
  559.             KillPicture(picH);
  560.  
  561.  
  562.             }
  563.         else
  564.             (*gAppCopyProc)(n);
  565.         }
  566.     }
  567.  
  568. void BEPaste(short n)
  569.     {
  570.     if(!SystemEdit(4))
  571.         (*gAppPasteProc)(n);
  572.     }
  573.  
  574. void BEClear(short n)
  575.     {
  576.     if(!SystemEdit(5))
  577.         (*gAppClearProc)(n);
  578.     }
  579.  
  580. void BENull(void){}
  581.  
  582.  
  583. /*----------------
  584.     Menu Action Routines
  585. ----------------*/
  586.  
  587. Boolean DoKeyPress(long k)
  588.     {
  589.     register long thePoint;
  590.     register Boolean didIt;
  591.  
  592.     thePoint = MenuKey((char)k);
  593.     didIt = (thePoint>>16) != 0;
  594.     if(didIt)
  595.         MenuPoint(thePoint);
  596.  
  597.     return didIt;
  598.     }
  599.     
  600. void MenuClick(Point p)
  601.     {
  602.     KeyMap     theKeys;
  603.     Boolean    putBack = false;
  604.     short    oldID;
  605.     
  606.     if (phantomMenuH) {
  607.     GetKeys(theKeys);
  608.         
  609.         if ((theKeys[1]&4) == 0) {
  610.             putBack = true;
  611.             oldID = (**phantomMenuH).menuID;
  612.             DeleteMenu( oldID );
  613.             }
  614.         }
  615.     MenuPoint(MenuSelect(p));
  616.     if (putBack)
  617.         {
  618.         InsertMenu(phantomMenuH,oldID);
  619.         }
  620.     }
  621.  
  622. void MenuPoint(long theclick)
  623.     {
  624.     register short mID,mItem;
  625.     char DAname[30];
  626.     short wNum;
  627.     TEasyWindow *thisWindow;
  628.     register beMenuProcPtr aProc;
  629.     register TEasyMenuItem *emi;
  630.  
  631.     mID = theclick>>16;
  632.     mItem = theclick & 0xffff;
  633.  
  634.     if(mID == 0) return;
  635.  
  636.     if(mID == 1)                            /* Apple menu */
  637.         {
  638.         if(mItem == 1)                        /* Its either the about box */
  639.             DoMyAbout();
  640.         else    
  641.             {                                    /* Or a DA */
  642.             GetItem(gMenuHandleList[1],mItem,(StringPtr)DAname);
  643.             OpenDeskAcc((StringPtr)DAname);
  644.             }
  645.         }
  646.     else
  647.         {
  648.         wNum = gLastFrontWindowNumber;
  649.         thisWindow = GoodWNum(wNum);
  650.         if(thisWindow)                                    /* if one of our window in front, setport    */
  651.             SetPort(thisWindow->wWindow);
  652.  
  653.         emi = &gMenu[mID][0];
  654.         aProc = emi->proc;
  655.         if(aProc)                                        /* call the menu's routine, if any        */
  656.             (*aProc)(wNum,mItem,gMenu[mID][mItem].ref);
  657.  
  658.         emi = &gMenu[mID][mItem];
  659.         aProc = emi->proc;
  660.         if(aProc)                                        /* call the item's routine, if any        */
  661.             (*aProc)(wNum,mItem,emi->ref);
  662.         }
  663.  
  664.     HiliteMenu(0);
  665.     }
  666.  
  667. char dAbout[] = "\pAbout ";
  668.  
  669. void StartMenus(void)
  670. /*
  671.  * Start with just an About box, and some DA's.
  672.  */
  673.     {
  674.     char aboutS[255];
  675.     MenuHandle applemenu;
  676.  
  677.     BlockMove(&dAbout[0],aboutS,dAbout[0]+1);            /* "About" */
  678.     BlockMove((StringPtr )0x910 + 1,aboutS + aboutS[0] + 1, *(StringPtr )0x910); /* ProgName */
  679.     aboutS[0] += *((StringPtr )0x910);
  680.     aboutS[aboutS[0] + 1] = '…';
  681.     aboutS[0]++;
  682.  
  683.     applemenu = NewMenu(1,(StringPtr)"\p");                /* Apple menu: ID 1                    */
  684.     AppendMenu(applemenu,(StringPtr)aboutS);
  685.     AppendMenu(applemenu,(StringPtr)"\p(-");
  686.     AddResMenu(applemenu,'DRVR');
  687.     InsertMenu(applemenu,0);
  688.     DrawMenuBar();
  689.     gMenuHandleList[1] = applemenu;
  690.     gMenu[1][0].enable = true;
  691.  
  692.     gMenuCount = 1;                        /* Next menu added will be ID 2        */
  693.     gCurrentMenu = 1;
  694.     gMenuLength[1] = 0;                    /* No items, really, in Apple menu        */
  695.     }
  696.  
  697. MenuHandle InstallMenu(StringPtr s,beMenuProcPtr action,short ref)
  698. /*
  699.  * Start a new menu with name s
  700.  */
  701.     {
  702.     register TEasyMenuItem *emi;
  703.     register MenuHandle mh;
  704.  
  705.     gMenuCount++;                                /* new menu                        */
  706.     gCurrentMenu = gMenuCount;
  707.  
  708.     if(*s > kMenuNameMax-1)
  709.         *s = kMenuNameMax-1;
  710.  
  711.     gMenuLength[gCurrentMenu] = 0;
  712.     mh = NewMenu(gCurrentMenu,(StringPtr)s);
  713.     gMenuHandleList[gCurrentMenu] = mh;
  714.     InsertMenu(mh,0);
  715.  
  716.     emi = &gMenu[gCurrentMenu][0];
  717.     emi->enable = ref >= 0;
  718.     if(!emi->enable)
  719.         {
  720.         DisableItem(mh,0);
  721.         ref =- ref;
  722.         }
  723.     emi->proc = action;
  724.     emi->ref = ref;
  725.  
  726.     gInvalidMenuBar = true;                    /* redraw soon */
  727.     BlockMove(s,gMenuName[gCurrentMenu],*s+1);
  728.     return mh;
  729.     }
  730.  
  731. void InstallMenuItem(StringPtr s,beMenuProcPtr action,short ref)
  732. /*
  733.  * Add an item to the last menu, and associate a routine with it.
  734.  */
  735.     {
  736.     register MenuHandle mh;
  737.     register TEasyMenuItem *emi;
  738.     register short item;
  739.  
  740.  
  741.     mh = gMenuHandleList[gCurrentMenu];
  742.     gMenuLength[gCurrentMenu]++;
  743.     item = gMenuLength[gCurrentMenu];
  744.     emi = &gMenu[gCurrentMenu][item];
  745.  
  746.     if (ref < 0)
  747.         {
  748.         DisableItem(mh,item);
  749.         ref =- ref;
  750.         emi->enable = 0;
  751.         }
  752.     else
  753.         emi->enable = 1;
  754.  
  755.     AppendMenu(mh,(StringPtr)s);
  756.     emi->proc = action;
  757.     emi->ref = ref;
  758.     emi->mark = 0;
  759.     if(*(s+*s-1) == '/')
  760.         emi->cmdEquiv = *(s+*s);
  761.     else
  762.         emi->cmdEquiv = 0;
  763.     }
  764.  
  765. void DeleteMenuItem(short ref)
  766. /*
  767.  * Remove all menu items with
  768.  * refcon ref.
  769.  */
  770.     {
  771.     short menu;
  772.     short item;
  773.  
  774.     for(menu = 1; menu <= gMenuCount; menu++)
  775.         for(item = gMenuLength[menu]; item > 0; item--)
  776.             {
  777.             if(gMenu[menu][item].ref == ref)
  778.                 DeleteIndexedMenuItem(menu,item);
  779.             }
  780.     }
  781.  
  782. void DeleteIndexedMenuItem(short menu,short item)
  783.     {
  784.     StringPtr oldStrings;
  785.     MenuHandle mh;
  786.     short i;
  787.     short itemCount;
  788.     register TEasyMenuItem *emi;
  789.     register StringPtr w;
  790.  
  791.     itemCount = gMenuLength[menu];
  792.     mh = gMenuHandleList[menu];
  793.     oldStrings = (StringPtr)NewPtr(256 * (itemCount));
  794.     FailNil((long)oldStrings);
  795.  
  796.     for(i = 1; i<=itemCount; i++)
  797.         GetItem(mh,i,(StringPtr)&oldStrings[(i-1)*256]);
  798.  
  799.     DeleteMenu(menu);
  800.     DisposeMenu(mh);
  801.  
  802.     mh = NewMenu(menu,(StringPtr)gMenuName[menu]);
  803.     emi = &gMenu[menu][1];
  804.     w = oldStrings;
  805.     for(i = 1; i<=itemCount; i++)
  806.         {
  807.         if(i != item)
  808.             {
  809.             if(emi->cmdEquiv)
  810.                 {
  811.                 *(w+*w+1) = '/';
  812.                 *(w+*w+2) = emi->cmdEquiv;
  813.                 *w = *w + 2;
  814.                 }
  815.             AppendMenu(mh,(StringPtr)w);
  816.             }
  817.         emi++;
  818.         w += 256;
  819.         }
  820.  
  821.     emi = &gMenu[menu][item];
  822.     for(i = item; i<itemCount; i++)
  823.         {
  824.         *emi = *(emi+1);
  825.         emi++;
  826.         }
  827.  
  828.     gMenuLength[menu]--;
  829.     itemCount--;
  830.  
  831.     emi = &gMenu[menu][1];
  832.     for(i = 1; i<=itemCount; i++)
  833.         {
  834.         if(!emi->enable)
  835.             DisableItem(mh,i);
  836.         if(emi->mark)
  837.             SetItemMark(mh,i,emi->mark);
  838.         emi++;
  839.         }
  840.  
  841.     InsertMenu(mh,menu+1);
  842.     DisposPtr((Ptr)oldStrings);
  843.     }
  844.  
  845. void InstallEditMenu(beWNumCallProcPtr Xundo,
  846.         beWNumCallProcPtr Xcut,
  847.         beWNumCallProcPtr Xcopy,
  848.         beWNumCallProcPtr Xpaste,
  849.         beWNumCallProcPtr Xclear)
  850.     /*
  851.      * Start an edit menu, and put the first six things in.
  852.      */
  853.     {
  854.     gAppUndoProc = Xundo;
  855.     gAppCutProc = Xcut;
  856.     gAppCopyProc = Xcopy;
  857.     gAppPasteProc = Xpaste;
  858.     gAppClearProc = Xclear;
  859.  
  860.     InstallMenu((StringPtr )"\pEdit",nil,0);
  861.     InstallMenuItem((StringPtr )"\px/Z",(beMenuProcPtr)BEUndo,-mUndo);            /* barfs because it is static */
  862.     InstallMenuItem((StringPtr )"\p(-",(beMenuProcPtr)BENull,0);
  863.     InstallMenuItem((StringPtr )"\px/X",(beMenuProcPtr)BECut,-mCut);
  864.     InstallMenuItem((StringPtr )"\px/C",(beMenuProcPtr)BECopy,-mCopy);
  865.     InstallMenuItem((StringPtr )"\px/V",(beMenuProcPtr)BEPaste,-mPaste);
  866.     InstallMenuItem((StringPtr )"\px/B",(beMenuProcPtr)BEClear,-mClear);
  867.  
  868.     gMenuEdit = gMenuHandleList[gCurrentMenu];
  869.  
  870.     EnDisEdits(-1,-1,-1,-1,-1);
  871.     }
  872.  
  873. void SetMenuItem(short ref,char enable,char isMarked,char mark,StringPtr s)
  874. /*
  875.   * Set all items with the reference number to the
  876.   * enable/disable state, with mark, and name s.
  877.   * pass enable + to enable, - to disable, and
  878.   * zero to leave alone.
  879.   */
  880.     {
  881.     short m,i;
  882.     MenuHandle mh;
  883.     register TEasyMenuItem *emi;
  884.  
  885.     for(m=1; m<=gMenuCount; m++)
  886.         {
  887.         mh = gMenuHandleList[m];
  888.         for(i=gMenuLength[m]; i>=0; i--)
  889.             {
  890.             emi = &gMenu[m][i];
  891.             if(emi->ref == ref)
  892.                 {
  893.                 if(enable)
  894.                     {
  895.                     if(!i)
  896.                         gInvalidMenuBar = true;
  897.                     if(enable > 0)
  898.                         {
  899.                         emi->enable = 1;
  900.                         EnableItem(mh,i);
  901.                         }
  902.                     else
  903.                         {
  904.                         emi->enable = 0;
  905.                         DisableItem(mh,i);
  906.                         }
  907.                     }
  908.                 if(i > 0)                    /* these only apply to items */
  909.                     {
  910.                     if(isMarked)
  911.                         if(isMarked > 0)
  912.                             {
  913.                             emi->mark = mark;
  914.                             SetItemMark(mh,i,mark);
  915.                             }
  916.                         else
  917.                             {
  918.                             emi->mark = 0;
  919.                             SetItemMark(mh,i,0);
  920.                             }
  921.                     if(s)
  922.                         SetItem(mh,i,(StringPtr)s);
  923.                     }
  924.                 }
  925.             }
  926.         }
  927.     }
  928.  
  929.  
  930.  
  931. void EnDisEdits(short Eundo,short Ecut,short Ecopy,short Epaste,short Eclear)
  932. /*
  933.  * For each edit menu entry,
  934.  * -1=disable, 1=enable, 0=leave alone.
  935.  */
  936.     {
  937.     SetMenuItem(mUndo,Eundo,false,0,(StringPtr )"\pUndo");
  938.     SetMenuItem(mCut,Ecut,false,0,(StringPtr )"\pCut");
  939.     SetMenuItem(mCopy,Ecopy,false,0,(StringPtr )"\pCopy");
  940.     SetMenuItem(mPaste,Epaste,false,0,(StringPtr )"\pPaste");
  941.     SetMenuItem(mClear,Eclear,false,0,(StringPtr )"\pClear");
  942.     }
  943.  
  944. void SetCurrentMenu(short ref)
  945. /*
  946.  * Set which menu will take
  947.  * future "InstallMenuItem"s.
  948.  */
  949.     {
  950.     register short i;
  951.  
  952.     for(i = 0; i<gMenuCount; i++)
  953.         {
  954.         if(gMenu[i][0].ref == ref)
  955.             gCurrentMenu = i;
  956.         }
  957.     }
  958.  
  959. long DisableAllMenus(void)
  960. /*
  961.  * Disable all menus, as for a modal dialog,
  962.  * and return a long with the masks of which should get reenabled.
  963.  */
  964.     {
  965.     long result;
  966.     long mask;
  967.     TEasyMenuItem *emi;
  968.     short i;
  969.  
  970.     result = 0;
  971.     mask = 1;
  972.     for(i = 0; i<kMMax; i++)
  973.         {
  974.         emi = &gMenu[i][0];
  975.         if(emi->enable)
  976.             {
  977.             DisableItem(gMenuHandleList[i],0);
  978.             result |= mask;
  979.             }
  980.         mask <<= 1;
  981.         }
  982.     DrawMenuBar();
  983.     return result;
  984.     }
  985.  
  986. void EnableAllMenus(long saveMenus)
  987. /*
  988.  * Enable menus according to the mask returned by DisableAllMenus().
  989.  */
  990.     {
  991.     long mask;
  992.     short i;
  993.  
  994.     mask = 1;
  995.     for(i = 0; i<kMMax; i++)
  996.         {
  997.         if(saveMenus & mask)
  998.             EnableItem(gMenuHandleList[i],0);
  999.         mask <<= 1;
  1000.         }
  1001.     DrawMenuBar();
  1002.     }
  1003.  
  1004.  
  1005. short ScanWindowList(WindowPtr w)
  1006. /*
  1007.   * return a window number from a WindowPeek,
  1008.   * or -1 if no known window.
  1009.   */
  1010.     {
  1011.     short i;
  1012.     TEasyWindow *wo;
  1013.  
  1014.     wo= &gEasyWindowList[0];
  1015.  
  1016.     for(i=0; i<gEasyWindowListSize; i++)
  1017.         {
  1018.         if (wo->wUsed && (wo->wWindow==w))
  1019.             return i;
  1020.         wo++;
  1021.         }
  1022.     return -1;
  1023.     }
  1024.  
  1025.  
  1026. /*----------------
  1027.     Mouse Action Routines
  1028. ----------------*/
  1029. void DoMouseClick(EventRecord *event)
  1030.     {
  1031.     WindowPtr w;
  1032.     short part;
  1033.     register short wNum;
  1034.     register TEasyWindow *thisEasyWindow;
  1035.     Point p;
  1036.     Rect r;
  1037.     Boolean tookEvent;
  1038.  
  1039.     p = event->where;
  1040.     part = FindWindow (p, &w);
  1041.     wNum = ScanWindowList(w);
  1042.     thisEasyWindow = GoodWNum(wNum);
  1043.  
  1044.     switch (part)
  1045.         {
  1046.         case inDesk:
  1047.             break;
  1048.  
  1049.         case inMenuBar:
  1050.             MenuClick(p);
  1051.             break;
  1052.         
  1053.         case inSysWindow:
  1054.             SystemClick(event,w);
  1055.             break;
  1056.         
  1057.         case inContent:
  1058.         contentClick:
  1059.             if (w != FrontWindow())                /* If clicked on a non-front window, */
  1060.                 SelectWindow(w);                            /* bring it to the front. */
  1061.             else if(thisEasyWindow)                            /* Click on front window: give click */
  1062.                 {                                        /* to window's click routine. */
  1063.                 SetPort(w);
  1064.                 GlobalToLocal(&p);
  1065.  
  1066.                 ClipRect(&gBigRect);
  1067.                 SetOrigin(0,0);
  1068.  
  1069.                 if(thisEasyWindow && thisEasyWindow->wEventProc)
  1070.                     (*thisEasyWindow->wEventProc)(wNum,event,&tookEvent);
  1071.                 else
  1072.                     tookEvent = false;
  1073.  
  1074.                 if(!tookEvent)
  1075.                     {
  1076.                     register beClickProcPtr fp;
  1077.  
  1078.                     fp = thisEasyWindow->wClickProc;
  1079.                     if(fp)
  1080.                         (*fp)(wNum,p,
  1081.                                 event->modifiers);
  1082.                     }
  1083.                 }
  1084.             break;
  1085.  
  1086.         case inDrag:
  1087.             if(((thisEasyWindow->flags & wCoolDrag)!=0)
  1088.                     ^ ((event->modifiers & optionKey)!=0))
  1089.                 {
  1090.                 gCoolDragPoint = event->where;
  1091.                 gCoolDragState = 1;
  1092.                 gCoolDragEW = thisEasyWindow;
  1093.                 gCoolDragWindowNumber = wNum;
  1094.                 if(!(event->modifiers & 256))
  1095.                     SelectWindow(w);
  1096.                 }
  1097.             else
  1098.                 if(Button())                                /* for quick title-bar clicks */
  1099.                     {
  1100.                     beMoveWindowProcPtr fp;
  1101.  
  1102.                     DragWindow(w,event->where,&gBigRect);
  1103.                     fp = thisEasyWindow->wMoveWindowProc;
  1104.                     if(fp)
  1105.                         (fp)(wNum);                    
  1106.                     }
  1107.                 else
  1108.                     SelectWindow(w);
  1109.             break;
  1110.  
  1111.         case inGrow:
  1112.             if(thisEasyWindow && (thisEasyWindow->flags & wGrowable))
  1113.                 {
  1114.                 long oldSize,newSize;
  1115.                 beGrowWindowProcPtr fp;
  1116.                 beResizeProcPtr rsfp;
  1117.                 
  1118.                 SetPort(w);
  1119.                 GetGrowRect(w,&r);
  1120.                 InvalRect(&r);
  1121.  
  1122.                 fp = thisEasyWindow->wGrowWindowProc;
  1123.                 if(fp)
  1124.                     (*fp)(&newSize,wNum,w,event->where,&gResizeLim);
  1125.                 else
  1126.                     newSize = GrowWindow(w,event->where,&gResizeLim);
  1127.  
  1128.                 rsfp = thisEasyWindow->wResizeProc;
  1129.                 if(rsfp)
  1130.                     {
  1131.                     oldSize = ((long)(w->portRect.bottom-w->portRect.top)<<16) |
  1132.                             (w->portRect.right-w->portRect.left);
  1133.                     (*rsfp)(wNum,(Point *)&oldSize,(Point *)&newSize,event->modifiers);
  1134.                     }
  1135.                 else
  1136.                     SizeWindow(w,newSize&0xffff,newSize>>16,1);
  1137.  
  1138.                 GetGrowRect(w,&r);
  1139.                 InvalRect(&r);
  1140.                 }
  1141.             else
  1142.                 goto contentClick;
  1143.             break;
  1144.  
  1145.         case inGoAway:
  1146.             if(thisEasyWindow)
  1147.                 if (TrackGoAway(w,event->where))
  1148.                     {
  1149.                     beGoAwayProcPtr fp;
  1150.                     
  1151.                     fp = thisEasyWindow->wGoAwayProc;
  1152.                     if(fp)
  1153.                         (*fp)(wNum);
  1154.                     }
  1155.             break;
  1156.  
  1157.         /*
  1158.          * The following way to handle zoom only
  1159.          * applies to zooming to 1 state.  This does
  1160.          * not handle zooming in and out between 2
  1161.          * states.  Check IM IV.
  1162.          */
  1163.  
  1164.         case inZoomIn:    /* zoomBox */
  1165.         case inZoomOut:
  1166.             if(thisEasyWindow)
  1167.                 {
  1168.                 if (TrackBox(w,event->where,part))
  1169.                     {
  1170.                     beWNumCallProcPtr fp;
  1171.                     
  1172.                     fp = thisEasyWindow->wZoomProc;
  1173.                     if(fp)
  1174.                         (*fp)(wNum);
  1175.                     }
  1176.                 }
  1177.             break;
  1178.         }
  1179.     }
  1180.  
  1181. /*----------------
  1182.     Window Action Routines
  1183. ----------------*/
  1184.  
  1185. WindowPtr InstallWindow(short iNum,StringPtr iTitle,Rect *iRect,short iType,short iFlags,
  1186.         beUpdateProcPtr iUpdate,beClickProcPtr iClick,beKeyProcPtr iKey,beGoAwayProcPtr iGoAway,
  1187.         beActivateProcPtr iActivate,beDeactivateProcPtr iDeactivate,beIdleProcPtr iIdle)
  1188. /*
  1189.  * Add a window to BigEasy's list. If the window is
  1190.  * already up somewhere, bring it to the front and
  1191.  * visualize it.
  1192.  */
  1193.     {
  1194.     TEasyWindow *thisWindow;
  1195.     Rect stagRect,**oldPos;
  1196.     Boolean isVisible;
  1197.     RgnHandle rh;
  1198.     KeyMap km;
  1199.     Boolean opt;
  1200.  
  1201.     GetKeys(km);
  1202.  
  1203.     opt =km[58/8] &  (1<< (58%8) );
  1204.  
  1205.     isVisible = iNum>0;
  1206.     if(!isVisible)
  1207.         iNum = -iNum;
  1208.  
  1209.     EnoughEasyWindows(iNum);            /* Make sure there's space for new one        */
  1210.     thisWindow = &gEasyWindowList[iNum];
  1211.  
  1212.     if (thisWindow->wUsed)                /* something already assigned to this window? */
  1213.         {
  1214.         Show(iNum);
  1215.         goto goHome;
  1216.         }
  1217.  
  1218.     oldPos = (Rect **)Get1Resource(kWinPosType,iNum);    /* attempt to find saved window position        */
  1219.     stagRect = *iRect;
  1220.  
  1221.     if(oldPos && !opt)                                    /* (option key "forgets" old window */
  1222.         OffsetRect(&stagRect,
  1223.                 (**oldPos).left - stagRect.left,(**oldPos).top - stagRect.top);
  1224.  
  1225.         {
  1226.         Rect lilRect;
  1227.  
  1228.         lilRect.top = stagRect.top - 10;
  1229.         lilRect.left = stagRect.left + 4;
  1230.         lilRect.bottom = lilRect.top + 1;
  1231.         lilRect.right = lilRect.left + 1;
  1232.  
  1233.         rh = NewRgn();
  1234.         RectRgn(rh,&lilRect);
  1235.         SectRgn(rh,*(RgnHandle *)0x9EE,rh);
  1236.         if(EmptyRgn(rh) && gWindowsInView)
  1237.             OffsetRect(&stagRect,50 - iRect->left,80 - iRect->top);
  1238.  
  1239.         if(gStaggerWindows)
  1240.             {
  1241.             gStagX = (gStagX + kStagStepX)%kStagLimX;
  1242.             gStagY = (gStagY + kStagStepY)%kStagLimY;
  1243.             OffsetRect(&stagRect,gStagX,gStagY);
  1244.             }
  1245.         DisposeRgn(rh);
  1246.         }
  1247.  
  1248.     thisWindow->wUsed = 1;
  1249.  
  1250.     if(gHasColor)
  1251.         thisWindow->wWindow = NewCWindow(0,&stagRect,(StringPtr)iTitle,isVisible,
  1252.                 ((iFlags & wZoomable) != 0) ? zoomDocProc : iType,
  1253.                 (WindowPtr)-1,iGoAway!=0,0);
  1254.     else
  1255.         thisWindow->wWindow = NewWindow(0,&stagRect,(StringPtr)iTitle,isVisible,
  1256.                 ((iFlags & wZoomable) != 0) ? zoomDocProc : iType,
  1257.                 (WindowPtr)-1,iGoAway!=0,0);
  1258.  
  1259.     SetPort(thisWindow->wWindow);
  1260.  
  1261.     thisWindow->flags = iFlags;
  1262.     thisWindow->wUpdateProc = iUpdate;
  1263.     thisWindow->wClickProc = iClick;
  1264.     thisWindow->wKeyProc = iKey;
  1265.     thisWindow->wGoAwayProc = iGoAway;
  1266.     thisWindow->wZoomProc = nil;
  1267.     thisWindow->wActivateProc = iActivate;
  1268.     thisWindow->wDeactivateProc = iDeactivate;
  1269.     thisWindow->wIdleProc = iIdle;
  1270.     thisWindow->wResizeProc = nil;
  1271.     thisWindow->wGrowWindowProc = nil;
  1272.     thisWindow->wMoveWindowProc = nil;
  1273.     thisWindow->wEventProc = nil;
  1274. goHome:
  1275.     return thisWindow->wWindow;
  1276.     }
  1277.  
  1278. void UninstallWindow(short iNum)
  1279.     {
  1280.     register TEasyWindow *thisWindow;
  1281.     register beDeactivateProcPtr fp;
  1282.  
  1283.     gCoolDragState = 0;                    /* just in case we were dragging the dissappeared window */
  1284.  
  1285.     if(!(thisWindow = GoodWNum(iNum)))
  1286.         return;
  1287.  
  1288.     SetPort(thisWindow->wWindow);
  1289.  
  1290.     fp = thisWindow->wDeactivateProc;
  1291.     if(fp)
  1292.         (*fp)(iNum);
  1293.     CloseWindow(thisWindow->wWindow);
  1294.     EnDisEdits(-1,-1,-1,-1,-1);
  1295.     thisWindow->wUsed = 0;
  1296.     }
  1297.  
  1298. void Show(short iNum)
  1299.     {
  1300.     register TEasyWindow *thisWindow;
  1301.  
  1302.     thisWindow = GoodWNum(iNum);
  1303.     if(thisWindow)
  1304.         {
  1305.         if(!((WindowPeek)(thisWindow->wWindow))->visible)    /* If so, just show it, and bring it to the front. */
  1306.             ShowWindow(thisWindow->wWindow);
  1307.         SelectWindow(thisWindow->wWindow);
  1308.         }
  1309.     }
  1310.  
  1311. void Hide(short iNum)
  1312. /*
  1313.   * Just do HideWindow to the
  1314.   * specified window number.
  1315.   */
  1316.     {
  1317.     register TEasyWindow *thisWindow;
  1318.  
  1319.     gCoolDragState = 0;                                    /* It might have been this window */
  1320.  
  1321.     thisWindow = GoodWNum(iNum);
  1322.     if(thisWindow)
  1323.         HideWindow(thisWindow->wWindow);
  1324.     }
  1325.  
  1326.     
  1327.  
  1328. void GetWindowRect(short n,Rect *r)
  1329. /*
  1330.   * return the window's current rectangle
  1331.   * in global coördinate space.
  1332.   */
  1333.     {
  1334.     TEasyWindow *thisWindow;
  1335.     WindowPtr g;
  1336.  
  1337.     if(!(thisWindow = GoodWNum(n)))
  1338.         return;
  1339.  
  1340.     if(thisWindow->wUsed)
  1341.         {
  1342.         g = thisWindow->wWindow;
  1343.         SetPort(g);
  1344.         *r = g->portRect;
  1345.         LocalToGlobal((Point *)r);
  1346.         LocalToGlobal((Point *)( (char*)r + 4));
  1347.         }
  1348.     }
  1349.         
  1350. WindowPtr GetWindowPtr(short n)
  1351. /*
  1352.   * return the windowptr for
  1353.   * the specified window number
  1354.   */
  1355.     {
  1356.     TEasyWindow *thisWindow;
  1357.     WindowPtr g;
  1358.  
  1359.     if(!(thisWindow = GoodWNum(n)))
  1360.         g = 0;
  1361.     else
  1362.         g = thisWindow->wWindow;
  1363.  
  1364.     return g;
  1365.     }
  1366.  
  1367. Boolean GetWindowVisible(short n)
  1368. /*
  1369.   * return true if the window exists,
  1370.   * and is visible, or false if its invisible
  1371.   * or doesn't exist.
  1372.   */
  1373.     {
  1374.     register WindowPtr g;
  1375.  
  1376.     g = GetWindowPtr(n);
  1377.     if(g)
  1378.         return ((WindowPeek)g)->visible;
  1379.     else
  1380.         return false;
  1381.     }
  1382.  
  1383. void SaveWindowPosition(short n)
  1384. /*
  1385.   * Save the position of window number n,
  1386.   * or all windows if n = -1;
  1387.   */
  1388.     {
  1389.     Rect **rH;
  1390.     register Rect *r;
  1391.     register short i;
  1392.     register short n1,n2;
  1393.     TEasyWindow *thisWindow;
  1394.  
  1395.     rH = (Rect **)NewHandle(sizeof(Rect));
  1396.     FailNil((long)rH);
  1397.     HLock((Handle)rH);
  1398.     r = *rH;
  1399.  
  1400.     if(n < 0)
  1401.         {
  1402.         n1 = 0;
  1403.         n2 = gEasyWindowListSize-1;
  1404.         }
  1405.     else
  1406.         n1 = n2 = n;
  1407.  
  1408.     for(i = n1; i<=n2; i++)
  1409.         {
  1410.         thisWindow = GoodWNum(i);
  1411.         if(thisWindow && thisWindow->wUsed)
  1412.             {
  1413.             GetWindowRect(i,r);
  1414.             if( !((WindowPeek)(thisWindow->wWindow))->visible )
  1415.                 SwapShort(r->left,r->right);
  1416.             Replace1Resource((Handle)rH,kWinPosType,i);
  1417.             }
  1418.         }
  1419.  
  1420.     DisposHandle( (Handle)rH );
  1421.     }
  1422.  
  1423. void ForgetWindowPosition(short n)
  1424. /*
  1425.   * Forget the saved window position n,
  1426.   * or all windows if n<0.
  1427.   */
  1428.     {
  1429.     register short i;
  1430.     register short n1,n2;
  1431.     register TEasyWindow *thisWindow;
  1432.  
  1433.     if(n < 0)
  1434.         {
  1435.         n1 = 0;
  1436.         n2 = gEasyWindowListSize-1;
  1437.         }
  1438.     else
  1439.         n1 = n2 = n;
  1440.  
  1441.     for(i = n1; i<=n2; i++)
  1442.         {
  1443.         thisWindow = GoodWNum(i);
  1444.         if(thisWindow && thisWindow->wUsed)
  1445.             Replace1Resource(0,kWinPosType,i);
  1446.         }
  1447.     }
  1448.  
  1449.  
  1450. void Replace1Resource(Handle h,long type,short id)
  1451. /*
  1452.   * This is AddResource with a
  1453.   * RmveResource if necessary.
  1454.   * Pass h==nil to delete the resource.
  1455.   */
  1456.     {
  1457.     Handle old;
  1458.  
  1459.     /*
  1460.      * A lame hack to prevent writing resources
  1461.      * to a lightspeed project file.
  1462.      */
  1463.     if( *(StringPtr)(0x910 + (*(StringPtr)0x910)) == 'π')
  1464.         {
  1465.         /* do nothing */
  1466.         }
  1467.     else
  1468.         {
  1469.  
  1470.         old = Get1Resource(type,id);
  1471.         if(old)
  1472.             RmveResource(old);
  1473.         if(h)
  1474.             {
  1475.             AddResource(h,type,id,(StringPtr)"\p");
  1476.             WriteResource(h);
  1477.             DetachResource(h);
  1478.             }
  1479.  
  1480.         }
  1481.     }
  1482.  
  1483. void CheckMenubar(void)
  1484.     {
  1485.     if(gInvalidMenuBar)
  1486.         {
  1487.         DrawMenuBar();
  1488.         gInvalidMenuBar = false;
  1489.         }
  1490.     }
  1491.  
  1492. /*----------------
  1493.     Event Routines
  1494. ----------------*/
  1495.  
  1496. Boolean HandleUpdateEvent(EventRecord *er)
  1497. /*
  1498.  * Update the appropriate window, if we know who it is.
  1499.  */
  1500.     {
  1501.     Boolean result;
  1502.     short wNum;
  1503.     TEasyWindow *thisEasyWindow;
  1504.     WindowPtr w;
  1505.  
  1506.     if(er->what != updateEvt)
  1507.         {
  1508.         result = false;
  1509.         goto goHome;
  1510.         }
  1511.  
  1512.     w = (WindowPtr)er->message;
  1513.  
  1514.     BeginUpdate(w);
  1515.     DrawControls(w);
  1516.  
  1517.     wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1518.     thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1519.  
  1520.     if(thisEasyWindow)
  1521.         {
  1522.         Rect visBounds;
  1523.         beUpdateProcPtr fp;
  1524.         
  1525.         result = true;
  1526.         visBounds = (**w->visRgn).rgnBBox;
  1527.         fp = thisEasyWindow->wUpdateProc;
  1528.         if(fp)
  1529.             {
  1530.             SetPort(thisEasyWindow->wWindow);                    /* Set port to window    */
  1531.             (*fp)(wNum);            /* Call drawing proc        */
  1532.             }
  1533.  
  1534.         SetOrigin(0,0);
  1535.  
  1536.         if (thisEasyWindow->flags & wGrowable)            /* Draw growbox, if...    */
  1537.             MyDrawGrowIcon(w);
  1538.  
  1539.         ClipRect(&gBigRect);
  1540.  
  1541.         }
  1542.     else
  1543.         result = false;
  1544.     EndUpdate(w);
  1545.  
  1546. goHome:
  1547.     return result;
  1548.     }
  1549.  
  1550.  
  1551. Boolean ActivateWindow(WindowPtr w, Boolean activate)
  1552.     {
  1553.     Boolean result;
  1554.     short wNum;
  1555.     TEasyWindow *thisEasyWindow;
  1556.     GrafPtr oldPort;
  1557.  
  1558.     GetPort(&oldPort);
  1559.  
  1560.     wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1561.     thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1562.  
  1563.     if(!thisEasyWindow)
  1564.         {
  1565.         result = false;
  1566.         goto goHome;
  1567.         }
  1568.  
  1569.     result = true;
  1570.  
  1571.     FrontDAEdits();
  1572.  
  1573.     if(thisEasyWindow)
  1574.         {
  1575.         SetPort(thisEasyWindow->wWindow);
  1576.         if(activate)
  1577.             {
  1578.             beActivateProcPtr fp;
  1579.             short copyItem;
  1580.  
  1581.             if(thisEasyWindow->flags & wCopyDraw)
  1582.                 copyItem = 1;
  1583.             else
  1584.                 copyItem = -1;
  1585.  
  1586.             EnDisEdits(-1,-1,copyItem,-1,-1);
  1587.             fp = thisEasyWindow->wActivateProc;
  1588.             if(fp)
  1589.                 (*fp)(wNum);
  1590.             }
  1591.         else
  1592.             {
  1593.             beDeactivateProcPtr fp;
  1594.                         
  1595.             EnDisEdits(-1,-1,-1,-1,-1);
  1596.             fp = thisEasyWindow->wDeactivateProc;
  1597.             if(fp)
  1598.                 (*fp)(wNum);
  1599.             }
  1600.  
  1601.         InitCursor();
  1602.         if (thisEasyWindow->flags & wGrowable)            /* Draw growbox, if...    */
  1603.             MyDrawGrowIcon(w);
  1604.         }
  1605.  
  1606. goHome:
  1607.     SetPort(oldPort);
  1608.     return result;
  1609.     }
  1610.  
  1611. Boolean HandleActivateEvent(EventRecord *er)
  1612. /*
  1613.  * Handle it, if we can find out who it is.
  1614.  */
  1615.     {
  1616.     Boolean result;
  1617.  
  1618.     result = true;
  1619.  
  1620.     switch(er->what)
  1621.         {
  1622.         case activateEvt:
  1623.             ActivateWindow((WindowPtr)er->message,er->modifiers & 1);
  1624.             break;        
  1625.  
  1626.         case kOSEvent:
  1627.             switch ((unsigned long) er->message >> 24)    /*  high byte of message  */
  1628.                 {
  1629.                  case kSuspendResumeMessage:
  1630.                     ActivateWindow(FrontWindow(),er->modifiers & 1);
  1631.                     break;
  1632.                 default:
  1633.                     result = false;
  1634.                     break;
  1635.                 }
  1636.             break;
  1637.  
  1638.         default:
  1639.             result = false;
  1640.             break;
  1641.         }
  1642. goHome:
  1643.     return result;
  1644.     }
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650. void EventLoop(void)
  1651.     {
  1652.     EventRecord er;
  1653.     short i;
  1654.     register short wNum;
  1655.     WindowPtr w;
  1656.     register TEasyWindow *thisEasyWindow;
  1657.     Boolean tookKey,tookEvent;
  1658.  
  1659.     CheckMenubar();
  1660.  
  1661.     WaitNextEvent(0xffff,&er,gSleep,nil);
  1662.         {
  1663.         gLastModifiers = er.modifiers;
  1664.         gLastEventTime = er.when;
  1665.  
  1666.         if(er.what > 5 && er.what < 12)                    /* update event or higher: in message    */
  1667.             w = (WindowPtr)er.message;
  1668.         else
  1669.             w = FrontWindow();                            /* else, use FrontW                    */
  1670.  
  1671.         if(er.what > 1)
  1672.             {
  1673.             wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1674.             thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1675.             }
  1676.         else
  1677.             thisEasyWindow = 0;
  1678.  
  1679.         SetPort(w);
  1680.  
  1681.         if(thisEasyWindow && thisEasyWindow->wEventProc)
  1682.             (*thisEasyWindow->wEventProc)(wNum,&er,&tookEvent);
  1683.         else
  1684.             tookEvent = 0;
  1685.  
  1686.         if(!tookEvent)
  1687.             switch (er.what)
  1688.                 {
  1689.                 case 0:    /* null event */
  1690.                     break;
  1691.     
  1692.                 case mouseDown:
  1693.                     FrontDAEdits();
  1694.                     DoMouseClick(&er);
  1695.                     break;
  1696.     
  1697.                 case keyDown:
  1698.                 case autoKey:
  1699.                     FrontDAEdits();
  1700.     
  1701.                     tookKey = false;
  1702.                     if( (!gMenuNeedsCmdKey) || (er.modifiers & 256) )
  1703.                         tookKey = DoKeyPress(er.message);
  1704.     
  1705.                     if(!tookKey && ((!gMenuNeedsCmdKey) || (er.modifiers & 256)) )
  1706.                         tookKey = CoolBigEasyCmdKeys(er.message & 0xFF);
  1707.     
  1708.                     if(!tookKey)
  1709.                         if(thisEasyWindow)
  1710.                             {
  1711.                             beKeyProcPtr fp;
  1712.                             
  1713.                             fp = thisEasyWindow->wKeyProc;
  1714.                             if(fp)
  1715.                                 {
  1716.                                 SetPort(thisEasyWindow->wWindow);                /* Set port to window    */
  1717.                                 (*fp)(wNum,            /* Call key proc        */
  1718.                                         (short)(er.message&0xff),            /* with the key */
  1719.                                         (short)((er.message>>8)&0xff),        /* the key code */
  1720.                                         er.modifiers);                        /* and the modifiers */
  1721.                                 }
  1722.                             }
  1723.                     break;
  1724.     
  1725.                 case updateEvt:
  1726.                     HandleUpdateEvent(&er);
  1727.                     break;
  1728.     
  1729.                 case activateEvt:
  1730.                     HandleActivateEvent(&er);
  1731.                     break;
  1732.     
  1733.                 case kOSEvent:
  1734.                     switch ((unsigned long) er.message >> 24)    /*  high byte of message  */
  1735.                         {
  1736.                          case kSuspendResumeMessage:
  1737.                             if(thisEasyWindow)                    /* just like activate event... */
  1738.                                 {
  1739.                                 ActivateWindow(FrontWindow(),
  1740.                                         er.message & kResumeMask);
  1741.                                 }
  1742.                         break;
  1743.                         }
  1744.                     break;
  1745.     
  1746.                 case kHighLevelEvent:
  1747.                     AEProcessAppleEvent(&er);
  1748.                     break;
  1749.                 case diskEvt:
  1750.                     if (er.message & 0xffff0000) {
  1751.                         Point where = {100,100};
  1752.                     //    DIBadMount(where, er.message);
  1753.                     }
  1754.                     break;    
  1755.                 default:
  1756.                     /*Debugger();/**/
  1757.                     ;
  1758.                 }
  1759.         }
  1760.  
  1761.     /*
  1762.       * See if we're doing a fake cool drag-window
  1763.       */
  1764.     if(gCoolDragState)
  1765.         {
  1766.         Point p,q;
  1767.  
  1768.         SetPort(gCoolDragEW->wWindow);
  1769.         GetMouse(&p);
  1770.         LocalToGlobal(&p);
  1771.         if( (p.v!=gCoolDragPoint.v) || (p.h!=gCoolDragPoint.h) )
  1772.             {
  1773.             q.h = gCoolDragEW->wWindow->portRect.left;
  1774.             q.v = gCoolDragEW->wWindow->portRect.top;
  1775.             LocalToGlobal(&q);
  1776.             MoveWindow(gCoolDragEW->wWindow,
  1777.                     q.h+p.h-gCoolDragPoint.h,
  1778.                     q.v+p.v-gCoolDragPoint.v,0);
  1779.             gCoolDragPoint = p;
  1780.  
  1781.                 {
  1782.                 beMoveWindowProcPtr fp;
  1783.  
  1784.                 fp = gCoolDragEW->wMoveWindowProc;
  1785.                 if(fp)
  1786.                     (fp)(gCoolDragWindowNumber);                    
  1787.                 }
  1788.  
  1789.             }
  1790.         if(!Button())
  1791.             gCoolDragState = 0;
  1792.         }
  1793.  
  1794.     SystemTask();
  1795.     w = FrontWindow();
  1796.     if ( w == gLastFrontIdle)                    /* Minor optimization, wins if the same        */
  1797.         wNum = gLastFrontWindowNumber;        /* window is frontmost for a while.            */
  1798.     else
  1799.         {
  1800.         wNum = ScanWindowList(w);
  1801.         gLastFrontIdle = w;
  1802.         gLastFrontWindowNumber = wNum;
  1803.         }
  1804.  
  1805.     if(er.what != mouseDown && er.what != activateEvt)    /* anything but a mousedown or [de]activate */
  1806.         {
  1807.         gIdleSeed ++;
  1808.         if(gIdleSeed & 1)    /* every other chance... */
  1809.             for(i = 1; i<gEasyWindowListSize; i++)
  1810.                 {
  1811.                 if(gEasyWindowList[i].wUsed && gEasyWindowList[i].wIdleProc)
  1812.                     {
  1813.                     SetPort(gEasyWindowList[i].wWindow);
  1814.                     (*gEasyWindowList[i].wIdleProc)
  1815.                             ((short)i,(Boolean)(w == gEasyWindowList[i].wWindow));
  1816.                     }
  1817.                 }
  1818.         }
  1819.  
  1820.     if (gMasterIdleProc)
  1821.         (*gMasterIdleProc)();
  1822.     }
  1823.  
  1824.  
  1825. Boolean CoolBigEasyCmdKeys(short key)
  1826.     {
  1827.     WindowRecord *w;
  1828.  
  1829.     switch(key)
  1830.         {
  1831.         /*
  1832.          * Rotate active window
  1833.          */
  1834.         case 9:        /* <tab> */
  1835.             w = *(WindowRecord **)0x9D6;        /* windowlist */
  1836.             if(w)
  1837.                 {
  1838.                 while (w->nextWindow)
  1839.                     w = w->nextWindow;
  1840.                 SelectWindow((WindowPtr)w);
  1841.                 }
  1842.             break;
  1843.  
  1844.         default:
  1845.             return false;
  1846.         }
  1847.     return true;
  1848.     }
  1849.  
  1850.  
  1851. void IdleWindow(short n)
  1852. /*
  1853.  * Idle window number n, or
  1854.  * -1 to idle all windows.
  1855.  */    
  1856.     {
  1857.     register short i;
  1858.     short lo,hi;
  1859.     WindowPtr w;
  1860.     register TEasyWindow *ew;
  1861.     GrafPtr oldPort;
  1862.  
  1863.     GetPort(&oldPort);
  1864.  
  1865.     if(n<0)
  1866.         {
  1867.         lo = 1;
  1868.         hi = gEasyWindowListSize;
  1869.         }
  1870.     else
  1871.         {
  1872.         lo = n;
  1873.         hi = n + 1;
  1874.         }
  1875.  
  1876.     w = FrontWindow();
  1877.     ew = &gEasyWindowList[lo];
  1878.  
  1879.     for(i = lo; i < hi; i++)
  1880.         {
  1881.         if(ew->wUsed && ew->wIdleProc)
  1882.             {
  1883.             SetPort(ew->wWindow);
  1884.             (*ew->wIdleProc)((short)i,ew->wWindow == w);
  1885.             }
  1886.         ew++;
  1887.         }
  1888.  
  1889.     SetPort(oldPort);
  1890.     SystemTask();
  1891.     }    
  1892.  
  1893. void MyDrawGrowIcon(WindowPtr w)
  1894.     {
  1895.     Rect r;
  1896.  
  1897.     SetPort(w);
  1898.     GetGrowRect(w,&r);
  1899.     ClipRect(&r);
  1900.     DrawGrowIcon(w);
  1901.     ClipRect(&gBigRect);
  1902.     }
  1903.  
  1904.  
  1905. void SetMasterOpenAppProc(beOpenAppProcPtr openAppProc)
  1906.     {
  1907.     gMasterOpenAppProc = openAppProc;
  1908.     if(gHasAppleEvents)
  1909.         AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  1910.                 (ProcPtr)BigEasyOpenAppThang, 0, false);
  1911.     }
  1912.  
  1913.  
  1914. void SetMasterOpenDocProc(beOpenDocProcPtr openDocProc)
  1915.     {
  1916.     gMasterOpenDocProc = openDocProc;
  1917.     if(gHasAppleEvents)
  1918.         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  1919.                 (ProcPtr)BigEasyOpenDocThang, 0, false);
  1920.     }
  1921.  
  1922. void SetMasterQuitAppProc(beQuitAppProcPtr quitAppProc)
  1923.     {
  1924.     gMasterQuitAppProc = quitAppProc;
  1925.     }
  1926.  
  1927. pascal OSErr BigEasyOpenAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon)
  1928.     {
  1929.     #pragma unused (reply,refCon,theEvent)
  1930.     return noErr;
  1931.     }
  1932.  
  1933. pascal OSErr BigEasyOpenDocThang(AppleEvent *message, AppleEvent *reply,long refCon)
  1934.     {
  1935.     FSSpec fSpec;
  1936.     AEDescList docList;
  1937.     long index, itemsInList;
  1938.     Size actualSize;
  1939.     AEKeyword keywd;
  1940.     DescType typeCode;
  1941.     OSErr thisError;
  1942.     #pragma unused (reply,refCon)
  1943.  
  1944.     thisError = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  1945.     if(thisError)
  1946.         goto goHome;
  1947.  
  1948.     thisError = MissedAEParameters(message);
  1949.     if(thisError)
  1950.         goto goHome;
  1951.  
  1952.     thisError = AECountItems(&docList, &itemsInList);
  1953.     if(thisError)
  1954.         goto goHome;
  1955.  
  1956.     for (index = 1; index <= itemsInList; index++)
  1957.         {
  1958.         thisError = AEGetNthPtr(&docList, index, typeFSS, &keywd, &typeCode,
  1959.                     (Ptr)&fSpec, sizeof(FSSpec), &actualSize);
  1960.         if(thisError)
  1961.             goto goHome;
  1962.  
  1963.         if(gMasterOpenDocProc)
  1964.             (*gMasterOpenDocProc)(&fSpec);
  1965.         }
  1966.  
  1967.     thisError = AEDisposeDesc(&docList);
  1968.  
  1969. goHome:
  1970.     return thisError;
  1971.     }
  1972.  
  1973. pascal OSErr BigEasyQuitAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon)
  1974.     {
  1975.     OSErr thisError;
  1976.     #pragma unused (reply,refCon)
  1977.  
  1978.     thisError = MissedAEParameters(theEvent);
  1979.     if (!thisError)
  1980.         {
  1981.         ++ gQuitApp;
  1982.     
  1983.         if(gMasterQuitAppProc)
  1984.             (*gMasterQuitAppProc)();
  1985.         }
  1986.  
  1987.     return thisError;
  1988.     }
  1989.  
  1990. OSErr MissedAEParameters (AppleEvent *message)
  1991.     {
  1992.     DescType typeCode;
  1993.     Size actualSize;
  1994.     OSErr err;
  1995.  
  1996.     err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  1997.             &typeCode, nil, 0L, &actualSize);
  1998.     if (err == errAEDescNotFound)
  1999.         return(noErr);
  2000.     return(err = noErr ? errAEEventNotHandled : err);
  2001.     }
  2002.  
  2003.  
  2004.  
  2005.  
  2006. void InitBigEasy(void)
  2007.     {
  2008.     long result;
  2009.  
  2010.     InstallMyExitToShell();
  2011.     gMasterOpenAppProc = nil;
  2012.     gMasterOpenDocProc = nil;
  2013.     gMasterIdleProc = nil;
  2014.     gAboutProc = nil;
  2015.     gQuitApp = false;
  2016.     gMenuNeedsCmdKey = true;
  2017.     gStaggerWindows = true;
  2018.     gWindowsInView = true;
  2019.     gSleep = 0;
  2020.     gInvalidMenuBar = false;
  2021.  
  2022.     SetRect(&gBigRect,-16000,-16000,16000,16000);
  2023.  
  2024.     gEasyWindowListH = (TEasyWindow**)NewHandle(sizeof(TEasyWindow));
  2025.     HLock((Handle)gEasyWindowListH);
  2026.     gEasyWindowList = *gEasyWindowListH;
  2027.     gEasyWindowList[0].wUsed = 0;
  2028.     gEasyWindowListSize = 1;
  2029.  
  2030.     gLastFrontIdle = (WindowPtr) 0;
  2031.     gLastFrontWindowNumber = -1;
  2032.  
  2033.     gCoolDragState = 0;
  2034.  
  2035.  
  2036. /*
  2037.  * 7.0 Feature stuff
  2038.  */
  2039.     gSystemVersion = (Gestalt('sysv', &result)) ? 0 : result;
  2040.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  2041.     gHasColor = (Gestalt('qdrw',&result)) ?
  2042.             false : (result & (1<<gestaltHasDeepGWorlds)) != 0;
  2043.  
  2044.     /*
  2045.      * The quit-app message, if available.
  2046.      */
  2047.     gMasterQuitAppProc = nil;
  2048.     if(gHasAppleEvents)
  2049.         AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  2050.                 (ProcPtr)BigEasyQuitAppThang, 0, false);
  2051.     }
  2052.  
  2053. void main(void)
  2054.     {
  2055. #if 0
  2056. #ifdef THINK_C_PROFILE
  2057.     freopen("profile output","w+",stdout);
  2058.  
  2059.     InitProfile(1000,50);
  2060. #endif THINK_C_PROFILE    
  2061. #endif
  2062.  
  2063.     MaxApplZone();
  2064.     MoreMasters();
  2065.     MoreMasters();
  2066.  
  2067.     InitToolbox();
  2068.     StartMenus();
  2069.  
  2070.     InitBigEasy();
  2071.     Bootstrap();
  2072.     
  2073.     #if THINK_C >= 5
  2074.         #if defined(STACK_KILLER) || defined(TIMING_PROFILE)
  2075.             prepStackKiller();        /** slime from HELL **/
  2076.             #ifdef TIMING_PROFILE
  2077.                 InitTimingProfile(150);    /* call depth */
  2078.             #endif TIMING_PROFILE
  2079.         #endif
  2080.     #endif
  2081.  
  2082.     while (!gQuitApp)
  2083.         EventLoop();
  2084.  
  2085.     FlushEvents(0xffff,0);
  2086.  
  2087.     #ifdef TIMING_PROFILE
  2088.         DumpProfile(0, 0, "\ptiming stats");
  2089.     #endif
  2090.  
  2091.     ExitToShell();
  2092.     }
  2093.  
  2094.